package com.ruoyi.framework.config;

import java.util.Map;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    entityManagerFactoryRef = "entityManagerFactoryBean",
    transactionManagerRef = "transactionManager",
    basePackages = {"com.ruoyi.project.small.repository"})
public class JpaConfig {

  @Autowired
  private JpaProperties jpaProperties;

  @Autowired
  private DataSource datasource;

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(
      EntityManagerFactoryBuilder builder) {
    return builder
        .dataSource(datasource)
        .properties(getVendorProperties(datasource))
        .packages("com.ruoyi.project.small.domain")
        .persistenceUnit("persistenceUnit")
        .build();
  }

  @Bean
  public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
    return entityManagerFactoryBean(builder).getObject().createEntityManager();
  }

  /**
   * 加载配置信息
   *
   * @param dataSource 数据源
   * @return 配置缓存
   */
  private Map<String, String> getVendorProperties(DataSource dataSource) {
    return jpaProperties.getProperties();
  }

  @Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
    return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
  }
}
